home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 2
/
Atari Mega Archive CD - Volume 2.iso
/
minix
/
up1510b.tgz
/
up1510b
/
src
/
commands
/
animals.c
next >
Wrap
C/C++ Source or Header
|
1990-07-23
|
6KB
|
306 lines
/* animals - guessing game Authors: Terrence W. Holm & Edwin L. Froese */
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include <sgtty.h>
#include <ctype.h>
#include <unistd.h>
#include <stdio.h>
#define ANIMALS "/usr/lib/animals"
#define DEFAULT_ANIMAL "beaver"
#define MAX_NODES 999 /* Enough for 500 animals */
#define MAX_LINE 90
void Abort();
char *Get_Animal();
char *Get_Question();
char *A_or_An();
char *Alloc();
struct node {
int question;
char *text;
int yes;
int no;
} animals[MAX_NODES];
int count = 0;
struct sgttyb old_tty_mode;
main(argc, argv)
int argc;
char *argv[];
{
char *animal_file = ANIMALS;
if (argc > 2) {
fprintf(stderr, "Usage: %s [ data_base ]\n", argv[0]);
exit(1);
}
if (argc == 2) animal_file = argv[1];
ioctl(0, TIOCGETP, &old_tty_mode);
signal(SIGINT, Abort);
signal(SIGQUIT, Abort);
if (access(animal_file, R_OK) == 0)
Read_Animals(animal_file);
else {
animals[0].question = 0;
animals[0].text = DEFAULT_ANIMAL;
count = 1;
}
while (Ask("\nAre you thinking of an animal?")) {
int i = 0;
while (1) {
if (animals[i].question) {
if (Ask(animals[i].text))
i = animals[i].yes;
else
i = animals[i].no;
} else {
printf("Were you thinking of %s %s",
A_or_An(animals[i].text), animals[i].text);
if (Ask("?")) printf("I knew it!\n");
else {
/* Insert a new question and animal name */
if (count + 2 > MAX_NODES)
Error("Too many animal names");
animals[count].question = 0;
animals[count].text = animals[i].text;
++count;
animals[count].question = 0;
printf("What animal were you thinking of? ");
animals[count].text = Get_Animal();
++count;
animals[i].question = 1;
printf("What question would distinguish %s %s from\n%s %s? ",
A_or_An(animals[count - 2].text), animals[count - 2].text,
A_or_An(animals[count - 1].text), animals[count - 1].text);
animals[i].text = Get_Question();
printf("For %s %s, the answer would be",
A_or_An(animals[count - 1].text), animals[count - 1].text);
if (Ask("?")) {
animals[i].yes = count - 1;
animals[i].no = count - 2;
} else {
animals[i].yes = count - 2;
animals[i].no = count - 1;
}
}
break;
}
} /* End while ( 1 ) */
}
ioctl(0, TIOCSETP, &old_tty_mode);
printf("\nThank you for playing \"animals\".\n");
printf("The animal data base is now being updated.\n");
Write_Animals(animal_file);
sleep(1);
printf("\nBye.\n");
exit(0);
}
/* Reading and writing the animal data base */
Read_Animals(animal_file)
char *animal_file;
{
FILE *f;
char buffer[MAX_LINE];
if ((f = fopen(animal_file, "r")) == NULL)
Error("Can not open animal data base");
while (fgets(buffer, MAX_LINE, f) != NULL) {
int string_length;
char *string;
buffer[strlen(buffer) - 1] = '\0';
swab(buffer, buffer, strlen(buffer));
if (buffer[0] == 'q') {
char *end = strchr(buffer, '?');
string_length = end - buffer;
animals[count].question = 1;
sscanf(end+1, "%d:%d",&animals[count].yes,&animals[count].no);
} else {
animals[count].question = 0;
string_length = strlen(buffer) - 1;
}
string = Alloc(string_length + 1);
string[0] = '\0';
strncat(string, buffer + 1, string_length);
animals[count].text = string;
count++;
}
fclose(f);
}
Write_Animals(animal_file)
char *animal_file;
{
FILE *f;
int i;
char buffer[MAX_LINE];
if ((f = fopen(animal_file, "w")) == NULL)
Error("Can not write animal data base");
for (i = 0; i < count; ++i) {
if (animals[i].question) sprintf(buffer, "q%s%d:%d", animals[i].text,
animals[i].yes, animals[i].no);
else
sprintf(buffer, "a%s", animals[i].text);
/* Make the data base a bit difficult to read */
swab(buffer, buffer, strlen(buffer));
fprintf(f, "%s\n", buffer);
}
fclose(f);
chmod(animal_file, 0666);
}
/* Reading data from the user */
int Ask(question)
char *question;
{
struct sgttyb new_tty_mode;
int response;
new_tty_mode = old_tty_mode;
new_tty_mode.sg_flags |= CBREAK;
ioctl(0, TIOCSETP, &new_tty_mode);
printf("%s ", question);
while ((response = getchar()) != 'y' && response != 'n')
printf("\n%s [yn]?", question);
putchar('\n');
ioctl(0, TIOCSETP, &old_tty_mode);
if (response == 'y')
return(1);
else
return(0);
}
char *Get_Animal()
{
char s[MAX_LINE];
char *text;
int text_length;
fgets(s, MAX_LINE, stdin);
text_length = strlen(s);
text = Alloc(text_length);
text[0] = '\0';
strncat(text, s, text_length - 1);
return(text);
}
char *Get_Question()
{
char s[MAX_LINE];
char *end;
char *text;
fgets(s, MAX_LINE, stdin);
/* Capitalize the first letter */
if (islower(s[0])) s[0] = toupper(s[0]);
/* Make sure the question ends with a '?' */
if ((end = strchr(s, '?')) == NULL)
s[strlen(s) - 1] = '?';
else
end[1] = '\0';
text = Alloc(strlen(s) + 1);
strcpy(text, s);
return(text);
}
/* Utility routines */
char *A_or_An(word)
char *word;
{
if (strchr("aeiouAEIOU", word[0]) == NULL)
return("a");
else
return("an");
}
char *Alloc(size)
int size;
{
char *malloc();
char *memory;
if ((memory = malloc(size)) == NULL)
Error("No room in memory for all the animals");
return(memory);
}
void Abort()
{
ioctl(0, TIOCSETP, &old_tty_mode);
printf("\nThank you for playing \"animals\".\n");
printf("Since you aborted, the animal data base will not be updated.\n");
sleep(1);
printf("\nBye.\n");
exit(1);
}
Error(message)
char *message;
{
ioctl(0, TIOCSETP, &old_tty_mode);
fprintf(stderr, "Error: %s\n", message);
exit(1);
}